package org.hawk.gwt.ppc.reflect.lang;

import java.lang.reflect.Modifier;

final class ObjectClassDelegate extends ClassDelegate<java.lang.Object> {
	
	static final ObjectClassDelegate instance = new ObjectClassDelegate();

	private ObjectClassDelegate() {
		super(Object.class);
		load(SystemClassLoader.getInstance(), true);
	}

	@Override
	public ClassDelegate<? super Object> getSuperclass() {
		return null;
	}

	protected String[] getConstructorSignatures() {
		return new String[]{"Object()"};
	}

	protected String[] getMethodSignatures() {
		return new String[] {
			"getClass()", "hashCode()", "equals(java.lang.Object)", "toString()"
		};
	}

	public int getModifiers(Object accessor, String signature) {
		super.getModifiers(accessor, signature);
		if (signature.equals("getClass()")) {
			return Modifier.PUBLIC | Modifier.FINAL | Modifier.NATIVE;
		} else if (signature.equals("hashCode()")) {
			return Modifier.PUBLIC | Modifier.NATIVE;
		} else if (signature.equals("equals(java.lang.Object)")) {
			return Modifier.PUBLIC;
		} else if (signature.equals("toString()")) {
			return Modifier.PUBLIC;
		}
		return 0;
	}

	public Object create(Object accessor, String signature, Object[] initargs) throws Throwable {
		super.create(accessor, signature, initargs);
		if (signature.equals("Object()")) {
			return new Object();
		}
		return null;
	}

	public Class<?> getReturnType(Object accessor, String signature) {
		super.getReturnType(accessor, signature);
		if (signature.equals("getClass()")) {
			return Class.class;
		} else if (signature.equals("hashCode()")) {
			return int.class;
		} else if (signature.equals("equals(java.lang.Object)")) {
			return boolean.class;
		} else if (signature.equals("toString()")) {
			return String.class;
		}
		return null;
	}

	public Object invoke(Object accessor, String signature, Object obj,
			Object[] parameters) throws Throwable {
		super.invoke(accessor, signature, obj, parameters);
		if (signature.equals("getClass()")) {
			return obj.getClass();
		} else if (signature.equals("hashCode()")) {
			return obj.hashCode();
		} else if (signature.equals("equals(java.lang.Object)")) {
			return obj.equals(parameters[0]);
		} else if (signature.equals("toString()")) {
			return obj.toString();
		}
		return null;
	}
	
	public Object createArray(Object accessor, int[] dimensions) {
		super.createArray(accessor, dimensions);
		switch (dimensions.length) {
		case 1: 
			return new Object[dimensions[0]];
		case 2:
			return new Object[dimensions[0]][dimensions[1]];
		case 3:
			return new Object[dimensions[0]][dimensions[1]][dimensions[2]];
		case 4:
			return new Object[dimensions[0]][dimensions[1]][dimensions[2]][dimensions[3]];
		case 5:
			return new Object[dimensions[0]][dimensions[1]][dimensions[2]][dimensions[3]][dimensions[4]];
		}
		return null;
	}
}
